<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\Common\Robot\Contracts\GatewayInterface;
use App\Common\Robot\Robot;
use App\CustHub\Constants\RoomInviteLogTypeConstants;
use App\CustHub\Mapper\ChRobotMapper;
use App\CustHub\Mapper\ChRoomInviteSchemeMapper;
use App\CustHub\Model\ChContact;
use App\CustHub\Model\ChEmployee;
use App\CustHub\Model\ChRobot;
use App\CustHub\Model\ChRoom;
use App\CustHub\Model\ChRoomInviteActiveRoom;
use App\CustHub\Model\ChRoomInviteScheme;
use App\CustHub\Model\ChRoomInviteSendTask;
use App\CustHub\Model\ChRoomMember;
use App\CustHub\Model\ChRoomPreset;
use App\CustHub\Model\ChRoomTag;
use App\Robot\Dto\CommonJobDto;
use App\Robot\Job\CommonJob;
use App\Robot\Service\SendRobotMessageService;
use Carbon\Carbon;
use Hyperf\Coroutine\Coroutine;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Redis\Redis;
use Mine\Abstracts\AbstractService;
use Mine\Annotation\Transaction;
use Mine\Exception\NormalStatusException;
use function Hyperf\Collection\collect;
use function Hyperf\Collection\data_get;
use function Hyperf\Coroutine\co;

class ChRoomInviteSchemeService extends AbstractService
{
    public $mapper;

    #[Inject]
    protected Redis $redis;

    #[Inject]
    protected ChRobotMapper $robotMapper;

    protected string $roomNameNumberPrefix = 'room_name_number:';

    public function __construct(ChRoomInviteSchemeMapper $mapper)
    {
        $this->mapper = $mapper;
    }

    public function getSchemeList(array $params)
    {
        $pageSize = $params['page_size'];
        $keyword = $params['keyword'] ?? '';
        $p = ChRoomInviteScheme::query()
            ->with(['activeRoomList'])
            ->where('main_uid',$params['main_uid'])
            ->when($keyword,function ($query) use ($keyword){
                $query->where('name', 'like', "%{$keyword}%");
            })
            ->orderBy('created_at', 'desc')
            ->paginate($pageSize);
        $targetRoomTypeConstants = [
            '按机器人选群','按群选择机器人','按条件筛选群'
        ];

        $inviteRule = [
            '按顺序发送全部群邀请','随机发送一个群邀请','按顺序发一个群邀请，群满发送下一个'
        ];
        $p->getCollection()->transform(function ($item) use ($targetRoomTypeConstants,$inviteRule){
            return [
                'id' => $item['id'],
                'name' => $item['name'],
                'room_count' => count($item->activeRoomList).'个群',
                'target_room_type' => $targetRoomTypeConstants[$item['target_room_type']],
                'invite_rule' => $inviteRule[$item['invite_rule']],
                'status' => $item['status'],
                'created_at' => $item->created_at->toDateTimeString(),
            ];
        });

        return $this->mapper->setPaginate($p);
    }

    public function getSelectList(array $params)
    {
        $keyword = $params['keyword'] ?? '';
        $p = ChRoomInviteScheme::query()
            ->with(['activeRoomList'])
            ->where('main_uid',$params['main_uid'])
            ->when($keyword,function ($query) use ($keyword){
                $query->where('name', 'like', "%{$keyword}%");
            })
            ->orderBy('created_at', 'desc')
            ->get();
        $targetRoomTypeConstants = [
            '按机器人选群','按群选择机器人','按条件筛选群'
        ];

        $inviteRule = [
            '按顺序发送全部群邀请','随机发送一个群邀请','按顺序发一个群邀请，群满发送下一个'
        ];
        $p->transform(function ($item) use ($targetRoomTypeConstants,$inviteRule){
            return [
                'id' => $item['id'],
                'name' => $item['name'],
                'room_count' => count($item->activeRoomList).'个群',
                'target_room_type' => $targetRoomTypeConstants[$item['target_room_type']],
                'invite_rule' => $inviteRule[$item['invite_rule']],
            ];
        });

        return $p;
    }

    /**
     * 新增数据.
     */
    #[Transaction]
    public function save(array $data): mixed
    {
        $data = $this->changeData($data);
        if (empty($data['name'])) {
            $data['name'] = '方案 ' . Carbon::now()->toDateTimeString();
        }
        $id = $this->mapper->save($data);
        if (!$id) {
            throw new NormalStatusException("新增失败，请重试");
        }

        $targetRoomType = $data['target_room_type'];
        $targetRoomConfig = $data['target_room_config'];
        $activeRoomData = [];
        if ($targetRoomType == 2) {
            //按条件筛选群
            $activeRoomData = $this->getActiveRoomList($data['main_uid'],$id, $targetRoomConfig);
        }else{
            $config = data_get($targetRoomConfig,'config',[]);
            foreach ($config as $item){
                $robotId = $item['robot_id'];
                $roomConfig = $item['room_config'];
                foreach ($roomConfig as $room){
                    $activeRoomData[] = [
                        'scheme_id' => $id,
                        'robot_id' => $robotId,
                        'scheme_type' => RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME,
                        'room_wxid' => $room['room_wxid'],
                        'genders' => json_encode($room['gender']),
                        'sort' => $room['sort'],
                        'created_at' => Carbon::now()->toDateTimeString(),
                        'updated_at' => Carbon::now()->toDateTimeString()
                    ];
                }
            }

        }

        if(!empty($activeRoomData)){
            ChRoomInviteActiveRoom::insert($activeRoomData);
        }
        return $id;
    }

    public function getInfo(array $params)
    {
        $id = $params['id'];

        $info = $this->mapper->findById($id);
        if(empty($info)){
            throw new NormalStatusException("请选择有效的方案");
        }
        $info = $info->toArray();
        $target_room_config = $info['target_room_config'];
        $config = data_get($target_room_config,'config',[]);
        if($info['target_room_type'] != 2){

            if(!empty($config)){
                $robotIds = array_column($config,'robot_id');
                $robotList = ChRobot::query()
                    ->selectRaw('id,nickname,avatar,corp_name')
                    ->whereIn('id',$robotIds)
                    ->get()
                    ->keyBy('id')
                    ->toArray();

                foreach ($config as $k=>$item){
                    $roomWxIds = array_column($item['room_config'],'room_wxid');
                    $robotId = $item['robot_id'];
                    $roomList = ChRoom::query()
                        ->selectRaw('id,room_name,room_wxid,room_avatar_url')
                        ->whereIn('room_wxid',$roomWxIds)
                        ->whereHas('robots',function ($query) use ($robotId){
                            $query->where('robot_id',$robotId);
                        })
                        ->get()
                        ->keyBy('room_wxid')
                        ->toArray();
                    $robotInfo = $robotList[$robotId];
                    $config[$k]['nickname'] = $robotInfo['nickname'] ?? '';
                    $config[$k]['avatar'] = $robotInfo['avatar'] ?? '';
                    $config[$k]['corp_name'] = $robotInfo['corp_name'] ?? '';
                    foreach ($item['room_config'] as $k2=>$room){
                        $roomInfo = $roomList[$room['room_wxid']];
                        $config[$k]['room_config'][$k2]['room_id'] = $roomInfo['id'] ?? '';
                        $config[$k]['room_config'][$k2]['room_name'] = $roomInfo['room_name'] ?? '';
                        $config[$k]['room_config'][$k2]['room_avatar_url'] = $roomInfo['room_avatar_url'] ?? '';
                    }
                }
            }
            $info['target_room_config']['config'] = $config;
        }else{
            $filter_mode = $target_room_config['filter_mode'];
            if($filter_mode == 1){
                $room_preset_id = $target_room_config['room_preset_id'];
                $roomPreset = ChRoomPreset::query()
                    ->where('id',$room_preset_id)
                    ->value('name');
                $info['target_room_config']['room_preset_name'] = $roomPreset;
            }else{
                $config = $target_room_config['config'];
                $roomTags = $config['room_tags'];
                if(!empty($roomTags)){
                    $roomTagsList = ChRoomTag::query()
                        ->select(['id','name'])
                        ->whereIn('id',$roomTags)
                        ->get();
                }else{
                    $roomTagsList = [];
                }
                $info['target_room_config']['config']['room_tags_list'] = $roomTagsList;
            }
        }

        if($info['auto_create_room_switch'] == 1){
            $auto_create_room_config = $info['auto_create_room_config'];

            $fixed_member = $auto_create_room_config['fixed_member'] ?? [];
            if(!empty($fixed_member)){
                $fixed_member_list = [];
                foreach ($fixed_member as $item){
                    $list = ChContact::query()
                        ->with(['robot' => function ($query) {
                            $query->selectRaw('id,nickname,avatar,corp_name');
                        }])
                        ->selectRaw('id,nickname,avatar,corp_short_name,is_wechat,robot_id,user_id')
                        ->where('main_uid',$params['main_uid'])
                        ->whereIn('user_id',$item['user_id_list'])
                        ->where('robot_id',$item['robot_id'])
                        ->groupBy('user_id')
                        ->get()->toArray();
                    $fixed_member_list = array_merge($fixed_member_list,$list);
                }
            }else{
                $fixed_member_list = [];
            }

            $employee_member = $auto_create_room_config['employee_member'] ?? [];
            if(!empty($employee_member)){
                $employee_list = ChEmployee::query()
                    ->select(['id','nickname','real_name','avatar_url','corp_name','user_id'])
                    ->where('main_uid',$params['main_uid'])
                    ->whereIn('user_id',$employee_member)
                    ->get()->toArray();
            }else{
                $employee_list = [];
            }

            $robot_id = data_get($auto_create_room_config,'remarketing.robot_id');
            if(!empty($robot_id)){
                $robotInfo = ChRobot::query()
                    ->selectRaw('id,nickname,avatar,corp_name')
                    ->where('id',$robot_id)
                    ->first();
                $info['auto_create_room_config']['remarketing']['nickname'] = $robotInfo['nickname'] ?? '';
                $info['auto_create_room_config']['remarketing']['avatar'] = $robotInfo['avatar'] ?? '';
            }

            $info['auto_create_room_config']['fixed_member_list'] = $fixed_member_list;
            $info['auto_create_room_config']['employee_list'] = $employee_list;
        }

        return $info;
    }


    /**
     * 更新一条数据.
     */
    #[Transaction]
    public function update(mixed $id, array $data): bool
    {
        $data = $this->changeData($data);
        $rst = $this->mapper->update($id, $data);

        $targetRoomType = $data['target_room_type'];
        $targetRoomConfig = $data['target_room_config'];
        $activeRoomData = [];
        if ($targetRoomType == 2) {
            //按条件筛选群
            $activeRoomData = $this->getActiveRoomList($data['main_uid'],$id, $targetRoomConfig);
            if(empty($activeRoomData)){
                $exists =ChRoomInviteActiveRoom::query()
                    ->where('scheme_id',$id)
                    ->where('scheme_type',RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME)
                    ->exists();
                if(!$exists){
                    ChRoomInviteActiveRoom::query()
                        ->where('scheme_id',$id)
                        ->where('scheme_type',RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME)
                        ->delete();
                }
                return $rst;
            }
        }else{
            $config = data_get($targetRoomConfig,'config',[]);
            foreach ($config as $item){
                $robotId = $item['robot_id'];
                $roomConfig = $item['room_config'];
                foreach ($roomConfig as $room){
                    $activeRoomData[] = [
                        'scheme_id' => $id,
                        'robot_id' => $robotId,
                        'scheme_type' => RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME,
                        'room_wxid' => $room['room_wxid'],
                        'genders' => json_encode($room['gender']),
                        'sort' => $room['sort'],
                        'created_at' => Carbon::now()->toDateTimeString(),
                        'updated_at' => Carbon::now()->toDateTimeString()
                    ];
                }
            }
        }
        $existRoomMap = ChRoomInviteActiveRoom::query()
            ->where('scheme_id',$id)
            ->where('scheme_type',RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME)
            ->get()
            ->map(function ($item){
                $key = md5($item['scheme_id'].$item['robot_id'].$item['scheme_type'].$item['room_wxid']);
                return [
                    'key' => $key,
                    'id' => $item['id']
                ];
            })->pluck('id','key')->toArray();

        $toUpdateData = [];
        $toInsertData = [];
        $toUpdateIds = [];
        foreach ($activeRoomData as $item){
            $key = md5($item['scheme_id'].$item['robot_id'].$item['scheme_type'].$item['room_wxid']);
            if(isset($existRoomMap[$key])){
                $item['id'] = $existRoomMap[$key];
                $toUpdateData[] = $item;
                $toUpdateIds[] = $existRoomMap[$key];
            }else{
                $toInsertData[] = $item;
            }
        }

        if(!empty($toUpdateData)){
            ChRoomInviteActiveRoom::query()->upsert($toUpdateData,'id',['genders','sort','updated_at']);
        }

        if(!empty($toInsertData)){
            ChRoomInviteActiveRoom::insert($toInsertData);
        }

        $toDeleteIds = array_diff(array_values($existRoomMap), $toUpdateIds);
        if(!empty($toDeleteIds)){
            ChRoomInviteActiveRoom::query()
                ->whereIn('id',$toDeleteIds)
                ->delete();
        }
        $this->mapper->delCache($id);
        return $rst;
    }

    public function changeSchemeStatus(array $data): bool
    {
        $info = $this->mapper->model::query()
            ->where('id',$data['id'])
            ->first();

        if(empty($info)){
            return false;
        }

        $info->status = $data['status'];
        return $info->save();
    }


    public function getActiveRoomList($mainUid,$schemeId, $targetRoomConfig)
    {
        $tempTableName = '';
        //按条件筛选群
        $filter_mode = $targetRoomConfig['filter_mode'];
        if ($filter_mode == 1) {
            //群组预设方案
            $config = ChRoomPreset::query()
                ->where('id', $targetRoomConfig['room_preset_id'])
                ->first();
            if(empty($config)){
                return [];
            }
        } else {
            $config = $targetRoomConfig['config'];
        }
        try {
            $query = ChRoom::query()
                ->with(['robots'])
                ->where('main_uid', $mainUid);
            //群名关键词
            $room_name_keyword_match_type = data_get($config, 'room_name_keyword_match_type', '');
            $room_name_keywords = data_get($config, 'room_name_keywords', []);
            if (filled($room_name_keyword_match_type) && !empty($room_name_keywords)) {
                if ($room_name_keyword_match_type == 0) {
                    $query->where(function ($query) use ($room_name_keywords) {
                        // 含任意一个关键词
                        foreach ($room_name_keywords as $keyword) {
                            $query->orWhere('room_name', 'like', "%{$keyword}%");
                        }
                    });
                } else {
                    $query->where(function ($query) use ($room_name_keywords) {
                        // 含所有关键词
                        foreach ($room_name_keywords as $keyword) {
                            $query->where('room_name', 'like', "%{$keyword}%");
                        }
                    });
                }
            }
            //群标签
            $room_tag_match_type = data_get($config, 'room_tag_match_type', '');
            $room_tags = data_get($config, 'room_tags', []);

            if (filled($room_tag_match_type)) {
                switch ($room_tag_match_type) {
                    case 0:
                        //满足任意一个标签
                        if (!empty($room_tags)) {
                            $query->whereHas('roomTags', function ($query) use ($room_tags) {
                                $query->whereIn('tag_id', $room_tags);
                            });
                        }
                        break;
                    case 1:
                        //满足所有标签
                        if (!empty($room_tags)) {
                            $query->whereHas('roomTags', function ($query) use ($room_tags) {
                                $query->whereIn('tag_id', $room_tags);
                            }, '=', count($room_tags));
                        }
                        break;
                    default:
                        //未打标签
                        $query->doesntHave('roomTags');
                        break;
                }
            }
            //在群角色
            $role = data_get($config, 'role', []);
            $roomRobotMap = [];
            if (!empty($role)) {
                list($query, $tempTableName, $roomRobotMap) = $this->useTempTableForRoomWxids($query, $mainUid, $role);
                if(empty($roomRobotMap)){
                    $query->whereRaw('1=0');
                    return $query->get();
                }
            }

            //群人数
            $min_members = data_get($config, 'min_members', '');
            $max_members = data_get($config, 'max_members', '');
            if (filled($min_members) || filled($max_members)) {
                if (filled($min_members)) {
                    $query->where('members_count', '>=', $min_members);
                }
                if (filled($max_members)) {
                    $query->where('members_count', '<=', $max_members);
                }
            }

            //建群日期
            $created_start_date = data_get($config, 'created_start_date', '');
            $created_end_date = data_get($config, 'created_end_date', '');
            if (filled($created_start_date) || filled($created_end_date)) {
                if (filled($created_start_date)) {
                    $query->where('create_time', '>=', strtotime($created_start_date));
                }
                if (filled($created_end_date)) {
                    $query->where('create_time', '<=', strtotime($created_end_date));
                }
            }

            $list = $query->get();
            $activeRoomData = [];
            foreach ($list as $key=>$item){
                if(!empty($roomRobotMap)){
                    $robotIds = $roomRobotMap[$item['id']];
                }else{
                    $robotIds = $item->robots()->pluck('id')->toArray();
                }
                foreach ($robotIds as $rk=>$robotId){
                    $activeRoomData[] = [
                        'scheme_id' => $schemeId,
                        'robot_id' => $robotId,
                        'scheme_type' => RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME,
                        'room_wxid' => $item['room_wxid'],
                        'genders' => json_encode([0,1,2]),
                        'sort' => $rk + 1,
                        'created_at' => Carbon::now()->toDateTimeString(),
                        'updated_at' => Carbon::now()->toDateTimeString()
                    ];
                }

            }
            return $activeRoomData;
        }catch (\Throwable $e){
            logger()->info('生效群列表获取失败'.$e->getMessage());
           return [];
        } finally {
            if ($tempTableName) {
                $this->cleanupTempTable($tempTableName);
            }
        }
    }

    private function useTempTableForRoomWxids($query, $mainUid, $role): array
    {

        $roomQuery = Db::table('ch_room_member as a')
            ->select(['b.id','c.id as robot_id'])
            ->join('ch_room as b', 'b.room_wxid', '=', 'a.room_wxid')
            ->join('ch_robot as c', 'c.user_id', '=', 'a.user_id')
            ->where('b.main_uid', $mainUid)
            ->where('c.main_uid', $mainUid);

        if(!in_array(2, $role)){
            if(in_array(0, $role) && in_array(1, $role)){
                $roomQuery->where(function ($query) {
                    $query->where('a.is_owner', 1)
                        ->orWhere('a.is_admin', 1);
                });
            }elseif (in_array(0, $role)){
                $roomQuery->where('a.is_owner', 1);
            }elseif (in_array(1, $role)){
                $roomQuery->where('a.is_admin', 1);
            }
        }

        $result = $roomQuery
            ->get();

        $roomWxIds = $result->pluck('id')->toArray();
        $roomRobotMap = $result->groupBy('id')->map(function ($item){
            return $item->pluck('robot_id')->toArray();
        })->toArray();
        if (empty($roomWxIds)) {
            return [$query, null,$roomRobotMap];
        }

        // 如果contactIds数量不大，直接使用WHERE IN
        if (count($roomWxIds) <= 1000) {
            return [$query->whereIn('id', $roomWxIds), null,$roomRobotMap];
        }

        // 创建临时表处理大量数据
        $tempTableName = 'temp_room_wxids_' . uniqid();

        try {
            // 创建临时表
            Db::statement("CREATE TEMPORARY TABLE {$tempTableName} (id INT PRIMARY KEY) ENGINE=MEMORY");

            // 分块插入数据
            $chunks = array_chunk($roomWxIds, 1000);
            foreach ($chunks as $chunk) {
                $values = implode('), (', $chunk);
                Db::statement("INSERT INTO {$tempTableName} (id) VALUES ({$values})");
            }

            // 使用JOIN替代WHERE IN
            $query = $query->join("{$tempTableName} as temp", 'ch_room.id', '=', 'temp.id');

            return [$query, $tempTableName,$roomRobotMap];
        } catch (\Throwable $e) {
            // 如果创建临时表失败，尝试回退到WHERE IN
            if ($tempTableName) {
                $this->cleanupTempTable($tempTableName);
            }

            // 回退到使用WHERE IN，即使数据量大
            return [$query->whereIn('id', $roomWxIds), null,$roomRobotMap];
        }
    }

    private function cleanupTempTable($tempTableName): void
    {
        try {
            Db::statement("DROP TEMPORARY TABLE IF EXISTS {$tempTableName}");
        } catch (\Throwable $e) {
            logger()->warning("删除临时表失败: {$tempTableName}, 错误: " . $e->getMessage());
        }
    }



    public function changeData(array $data)
    {
        $jsonFields = ['target_room_config', 'auto_create_room_config', 'resend_unjoined_config', 'resend_joined_config'];
        foreach ($jsonFields as $field) {
            if (!empty($data[$field])) {
                $data[$field] = json_decode($data[$field], true);
            } else {
                $data[$field] = [];
            }
        }
        return $data;
    }

    /**
     * @param array $params
     * @return array
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function getActiveRoomPageList(array $params): array
    {
        $params['scheme_type'] = RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME;

        $schemeInfo = ChRoomInviteScheme::query()
            ->where('id', $params['scheme_id'])
            ->first();
        if(empty($schemeInfo)){
            throw new NormalStatusException('请选择方案');
        }
        $params['group_user_count'] = $schemeInfo->room_member_limit;
        return container()->get(ChRoomInviteActiveRoomService::class)->getActiveRoomPageList($params);
    }

    /**
     * 设置进粉群状态
     * @param array $params
     * @return bool
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function setActiveRoomStatus(array $params): bool
    {
        return container()->get(ChRoomInviteActiveRoomService::class)->setActiveRoomStatus($params,RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME);
    }

    /**
     * 单个或批量软删除数据.
     */
    public function delete(array $ids): bool
    {
        $rst = false;
        if(! empty($ids)){
            $rst = $this->mapper->delete($ids);
            if($rst){
                foreach ($ids as $id){
                    $this->mapper->delCache($id);
                    $this->redis->del($this->roomNameNumberPrefix.$id.':'.RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME);
                }
            }

        }
        return  $rst;
    }


    public function getRobotListByFixedMember(array $params)
    {
        $fixedMember = json_decode($params['fixed_member'],true);
        $robotList = ChRobot::query()
            ->select(['id','nickname','avatar','corp_name','login_status'])
            ->where('main_uid',$params['main_uid'])
            ->whereIn('user_id',$fixedMember)
            ->get();

        return $robotList;
    }


    public function handle(array $data)
    {
        $robotId = $data['robot_id'];
        $schemeId = $data['scheme_id'];
        $userId = $data['user_id'];
        $gender = $data['gender'];
        logger()->info('新客户发送群邀请'.json_encode($data));
        $info = $this->mapper->findById($schemeId);
        if(empty($info)){
            return;
        }
        
        if($info->status != 1){
            return;
        }

        $robotInfo = $this->robotMapper->findById($robotId);
        $apiService = make(Robot::class,[$robotInfo->server_id,$robotInfo->uuid])->gateway();

        $activeRoomList = ChRoomInviteActiveRoom::query()
            ->where('scheme_id',$schemeId)
            ->where('robot_id',$robotId)
            ->where('scheme_type',RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME)
            ->where('status','<>',2)
            ->orderByRaw('status desc,sort asc')
            ->get();

        $activeRoomList = $activeRoomList->filter(function ($item) use ($gender){
            return in_array($gender,$item->genders);
        });

        if(!empty($activeRoomList)){
            //群成员上限
            $room_member_limit = $info->room_member_limit;

            $roomMemberCountMap = ChRoom::query()
                ->whereIn('room_wxid',$activeRoomList->pluck('room_wxid')->toArray())
                ->whereHas('robots',function ($query) use ($robotId){
                    $query->where('robot_id',$robotId);
                })->pluck('room_member_count','room_wxid')
                ->toArray();

            $fullRoomIds = [];
            foreach ($activeRoomList as $k=>$item){
                $roomMemberCount = $roomMemberCountMap[$item->room_wxid] ?? 0;
                if($roomMemberCount >= $room_member_limit){
                    $fullRoomIds[] = $item->id;
                    unset($activeRoomList[$k]);
                }
            }

            if(!empty($fullRoomIds)){
                ChRoomInviteActiveRoom::query()
                    ->whereIn('id',$fullRoomIds)
                    ->update([
                        'status' => 2
                    ]);
            }
        }

        $auto_create_room_switch = $info->auto_create_room_switch;
        if($activeRoomList->isEmpty() && $auto_create_room_switch){
            //不存在生效群，则创建群聊
            $auto_create_room_config = $info->auto_create_room_config;
            $roomName = $auto_create_room_config['room_name'];
            $roomNameNumber = $auto_create_room_config['room_number'];
            $key = $this->roomNameNumberPrefix.$schemeId.':'.RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME;
            $beforeRoomNameNumber = $this->redis->get($key);
            if(!empty($beforeRoomNameNumber) && $beforeRoomNameNumber > $roomNameNumber){
                $roomNameNumber = $beforeRoomNameNumber;
            }
            $this->redis->set($key,$roomNameNumber + 1);
            //群名称
            $roomName = $roomName.$roomNameNumber;
            //固定成员
            $fixed_member = $auto_create_room_config['fixed_member'] ?? [];
            $userIdList = [$userId];
            if(!empty($fixed_member)){
                foreach ($fixed_member as $item){
                    if($robotId == $item['robot_id']){
                        $exitsUserIdList = ChContact::query()
                            ->where('robot_id',$robotId)
                            ->whereIn('user_id',$item['user_id_list'])
                            ->pluck('user_id')
                            ->toArray();
                        $userIdList = array_merge($userIdList,$exitsUserIdList);
                    }
                }
            }

            $employee_member = $auto_create_room_config['employee_member'] ?? [];
            $userIdList = array_merge($userIdList,$employee_member);

            //群类型：0=多客户群 1=单客户
            $room_type = $auto_create_room_config['room_type'];

            $response = $apiService->createRoom($userIdList);
            if($response !== false){
                $roomId = $response['room_id'];
                $apiService->editRoomName($roomId,$roomName);

                if($room_type == 0){
                    //新增进分群
                    ChRoomInviteActiveRoom::query()->insert([
                        'scheme_id' => $schemeId,
                        'robot_id' => $robotId,
                        'room_wxid' => $roomId,
                        'scheme_type' => RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME,
                        'status' => 1,
                        'genders' => json_encode([0,1,2]),
                        'sort' => 0,
                        'created_at' => Carbon::now()->toDateTimeString(),
                        'updated_at' => Carbon::now()->toDateTimeString()
                    ]);
                }

                //发送营销数据
                $delayTime = 0;
                if(!empty($auto_create_room_config['proactive_marketing'])){
                    foreach ($auto_create_room_config['proactive_marketing'] as $item){
                        $messageData = [
                            'robot_id' => $robotInfo->id,
                            'to_id' => $roomId,
                            'msg_type' => $item['msg_type'],
                            'content' => $item['content']
                        ];
                        $delayTime = $delayTime + mt_rand(5,10);
                        container()->get(LowQueueService::class)->push(new CommonJob(new CommonJobDto(
                            classname: SendRobotMessageService::class,
                            method: 'handle',
                            data: $messageData
                        )),$delayTime);
                    }
                }
                //群内再次营销
                if(!empty($auto_create_room_config['remarketing'])){
                    $reSendRobotId = $auto_create_room_config['remarketing']['robot_id'];
                    $reSendContent = $auto_create_room_config['remarketing']['content'];
                    foreach ($reSendContent as $item){
                        $messageData = [
                            'robot_id' => $reSendRobotId,
                            'to_id' => $roomId,
                            'msg_type' => $item['msg_type'],
                            'content' => $item['content']
                        ];
                        $delayTime = $delayTime + mt_rand(5,10);
                        container()->get(LowQueueService::class)->push(new CommonJob(new CommonJobDto(
                            classname: SendRobotMessageService::class,
                            method: 'handle',
                            data: $messageData
                        )),$delayTime);
                    }
                }
                $resend_joined_switch = $info->resend_joined_switch;
                if($resend_joined_switch){
                    $resend_joined_config = $info->resend_joined_config;
                    $this->saveInviteSendTask($resend_joined_config,$robotId,$info->id,$userId,$roomId,1);
                }
            }
        }elseif($activeRoomList->isNotEmpty()){
            //发送群邀请 拉群规则0=按顺序发送全部群邀请 1=随机发送一个群邀请 2=按顺序发一个群邀请，群满发送下一个
            $invite_rule = $info->invite_rule;
            if($invite_rule == 0){
                //按顺序发送全部群邀请
                $delay = $invite_interval = $info->invite_interval;
                foreach ($activeRoomList as $item){
                    //发送群邀请
                    $this->inviteFriendToRoom($info,$apiService,$item,$userId);
                    //拉取时间时间
                    Coroutine::sleep($delay);
                    $delay = $delay + $invite_interval;
                }
            }elseif ($invite_rule == 1){
                //随机发送一个群邀请
                $activeRoom = collect($activeRoomList)->random(1)->first();
                $this->inviteFriendToRoom($info,$apiService,$activeRoom,$userId);
            }else{
                //按顺序发一个群邀请，群满发送下一个
                $activeRoom = collect($activeRoomList)->first();
                if($activeRoom->status != 1){
                    ChRoomInviteActiveRoom::query()
                        ->where('id',$activeRoom->id)
                        ->update([
                            'status' => 1
                        ]);
                }
                $this->inviteFriendToRoom($info,$apiService,$activeRoom,$userId);
            }
        }
    }

    private function inviteFriendToRoom(ChRoomInviteScheme $info,GatewayInterface $apiService,$activeRoom,string $userId)
    {
        $exclude_existing_switch = $info->exclude_existing_switch;
        if($exclude_existing_switch){
            //已在群聊不触发
            $exists = ChRoomMember::query()
                ->where('room_wxid',$activeRoom->room_wxid)
                ->where('user_id',$userId)
                ->where('is_out',0)
                ->exists();
            if($exists){
                return;
            }
        }

        $exclude_historical_switch = $info->exclude_historical_switch;
        if($exclude_historical_switch){
            //曾在群聊不触发
            $exists = ChRoomMember::query()
                ->where('room_wxid',$activeRoom->room_wxid)
                ->where('user_id',$userId)
                ->where('is_out',1)
                ->exists();
            if($exists){
                return;
            }
        }

        $apiService->inviteFriendToRoom($activeRoom->room_wxid,[$userId]);
        //未进群再次发送邀请
        $resend_unjoined_switch = $info->resend_unjoined_switch;
        if($resend_unjoined_switch){
            $resend_joined_config = $info->resend_unjoined_config;
            $this->saveInviteSendTask($resend_joined_config,$activeRoom->robot_id,$info->id,$userId,$activeRoom->room_wxid);
        }

        $resend_joined_switch = $info->resend_joined_switch;
        if($resend_joined_switch){
            $resend_joined_config = $info->resend_joined_config;
            $this->saveInviteSendTask($resend_joined_config,$activeRoom->robot_id,$info->id,$userId,$activeRoom->room_wxid,1);
        }
    }


    private function saveInviteSendTask($config,$robotId,$schemeId,$userId,$roomWxid,int $type = 0): void
    {
        $sendTaskData = [];
        foreach ($config as $item){
            //获取下次发送的时间
            if($item['sending_time_slot']['enabled'] == 1){
                $nextSendTime = $this->getNextSendTime(
                    $item['day'],
                    $item['hour'],
                    $item['minute'],
                    $item['sending_time_slot']['start_time'],
                    $item['sending_time_slot']['end_time']
                );
            }else{
                $nextSendTime = $this->getNextSendTime(
                    $item['day'],
                    $item['hour'],
                    $item['minute'],
                );
            }

            $sendTaskData = [
                'robot_id' => $robotId,
                'scheme_id' => $schemeId,
                'scheme_type' => RoomInviteLogTypeConstants::ROOM_INVITE_SCHEME,
                'user_id' => $userId,
                'room_wxid' => $roomWxid,
                'send_time' => $nextSendTime->timestamp,
                'content' => json_encode($item['content'], JSON_UNESCAPED_UNICODE),
                'type' => $type
            ];
        }
        !empty($sendTaskData) && ChRoomInviteSendTask::insert($sendTaskData);
    }


    function getNextSendTime(
        int $days,
        int $hours,
        int $minutes,
        string $startWindow = '',
        string $endWindow = ''
    ): Carbon {
        $base = Carbon::now()->addDays($days)->addHours($hours)->addMinutes($minutes);

        if(empty($startWindow) || empty($endWindow)){
            return $base;
        }

        $windowStart = Carbon::parse($base->format('Y-m-d') . ' ' . $startWindow);
        $windowEnd   = Carbon::parse($base->format('Y-m-d') . ' ' . $endWindow);

        if ($base->between($windowStart, $windowEnd)) {
            // 在允许时间段内，直接返回
            return $base;
        }

        if ($base->lt($windowStart)) {
            // 如果比窗口开始还早，就取窗口开始
            return $windowStart;
        }

        // 如果比窗口结束还晚，就推到下一天的窗口开始
        return $windowStart->addDay();
    }
}